﻿using System;
using breakoutsharp;
using breakoutsharp.visual.gameobject;

using System.Drawing;
namespace breakoutsharp.core
{
    class Collision
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        /// <param name="newBallPt"></param>
        /// <param name="rect"></param>
        public static void RectVsRectCollision(Ball b, PointF newBallPt, RectangleF rect)
        {
            /*ADVANCED COLLISION DETECTED ALGORITHM: built to give maximum control to the player
             * Ball Vs Paddle version
             * -----------------------
             * ball hit corner of paddle:
             *      - invert balls x/y direction
             *      - increase speed on ball
             * ball hit middleo of paddle
             *      - decrease speed a little bit
             *      - change direction towards directly up
             * ball hit between corner and middle
             *      - ball's direction changed toward that direction
             * 
             * Ball Vs block version
             * ----------------------
             * ball hit bottom or top:
             *      - invert y-direction
             * else
             *      - invert x-direction
            */

            bool cornerDeflection = true;

            //The square length of which its defined that the ball hit the cornwer of the paddle
            double cornerLength = rect.Width / 8;

            //The change in y axis for every step in x axis
            double ballGradient = (b.Location.Y - newBallPt.Y) / (b.Location.X - newBallPt.X);

            //left corner optimal direction: (-1.3, -1)
            //right corner optimal direction: ( 1.3, -1)

            /* Collision detection for hit on top of rectangle */
            float ballBottomStartY = b.Location.Y + b.Size.Height;
            float maxBallMovementOnXAxis = Math.Abs((newBallPt.X) - (b.Location.X));

            //top paddle line
            float topRectXStart = rect.X;
            float topRectXStop = rect.X + rect.Width;
            float topRectY = rect.Y;

            //startPoint.X + (ballAngle * stepInXDirection) = topY
            /* See how many steps the ball have to take on x-axis before the bottom of the ball will hit top of paddle */
            double stepInXDirection = Math.Abs((topRectY - ballBottomStartY) / (ballGradient));

            /* if the ball moves that long, then there is collision */
            if (stepInXDirection < maxBallMovementOnXAxis)
            {
                /* Ball hit the top of the rectangle*/
                double hitSpot = (b.Location.X + b.Size.Height / 2 + stepInXDirection) - rect.X;

                b.InvertVertical();
                return;
                ////// left corner
                ////if (hitSpot < cornerLength && cornerDeflection)
                ////{
                ////    //Here we should change the direction
                ////    if (b.IsGoingDown)
                ////    {
                ////        b.InvertVertical();
                ////    }

                ////    if (b.IsGoingRight)
                ////    {
                ////        b.InvertHorizontal();
                ////    }
                ////}
                ////else if (cornerDeflection && hitSpot > rect.Width - cornerLength)
                ////{
                ////    if (b.IsGoingDown)
                ////    {
                ////        b.InvertVertical();
                ////    }

                ////    if (b.IsGoingLeft)
                ////    {
                ////        b.InvertHorizontal();
                ////    }
                ////}
                ////else
                ////{
                ////    b.InvertVertical();
                ////}

                ////return;
            }

            Console.WriteLine("Starting check for buttom border collision");
            // -- CHECKING FOR HIT ON buttom BORDER OF rect; INCLUDING CORNERS
            //using ballGradient from above
            float ballTopY = b.Location.Y;

            //bottom rect line
            float bottomRectX = rect.X;
            float bottomRectXEnd = rect.X + rect.Width;
            var bottomRectY = rect.Y + rect.Height;

            stepInXDirection = (bottomRectY - ballTopY) / (ballGradient);

            if (stepInXDirection < maxBallMovementOnXAxis)
            {
                Console.WriteLine("HIT BOTTOM STUFF");

                double hitSpot = (b.Location.X + b.Size.Height / 2 + stepInXDirection) - rect.X;

                // left corner
                if (cornerDeflection && hitSpot < cornerLength)
                {
                    //Here we should change the direction
                    if (b.IsGoingUp)
                    {
                        b.InvertVertical();
                    }

                    if (b.IsGoingRight)
                    {
                        b.InvertHorizontal();
                    }
                }
                else if (cornerDeflection && hitSpot > rect.Width - cornerLength)
                {
                    if (b.IsGoingUp)
                    {
                        b.InvertVertical();
                    }

                    if (b.IsGoingLeft)
                    {
                        b.InvertHorizontal();
                    }
                }
                else
                {
                    b.InvertVertical();
                }

                return;
            }
        }
    }
}
